/*
 * Copyright (c) 2022, yifengling0. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. No personal names or organizations' names associated with the
 *    Atomthreads project may be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#include "drv_sys.h"
#include "syslog.h"
#include "console.h"
#include  "kassert.h"
#include "debug.h"
#include <string.h>


#define SYS_MIN_INT_SOURCE       0
#define SYS_MAX_INT_SOURCE       100

static struct irq_desc _irq_desc[SYS_MAX_INT_SOURCE + 1];

void interrupt_dummy_handler(int vector, void *param)
{
    SYSLOG(LOG_ERR, "Unhandled interrupt %d occurred!!!\n", vector);
    kassert(0);
}

void SysInterruptSetPriority(int vector, int level)
{
    if (vector > SYS_MAX_INT_SOURCE)
        return;
}

isr_handler_t SysInterruptIntall(int vector, isr_handler_t handler, void *param, const char *name)
{
    isr_handler_t    old_handler = NULL;

    if (vector > SYS_MAX_INT_SOURCE)
        return NULL;

    old_handler = _irq_desc[vector].handler;
    if (handler != NULL)
    {
        _irq_desc[vector].handler = (isr_handler_t)handler;
        _irq_desc[vector].param = param;
#ifdef COM_USING_INTERRUPT_INFO
        strncpy(_irq_desc[vector].name, name, COM_INTERRUPT_NAME_MAX - 1);
        _irq_desc[vector].counter = 0;
#endif
    }

    return old_handler;
}

void call_interupt_handler(int vector)
{
    isr_handler_t handler = _irq_desc[vector].handler;
    if (handler != NULL)
    {
#ifdef COM_USING_INTERRUPT_INFO
        _irq_desc[vector].counter++;
#endif
        _irq_desc[vector].handler(vector, _irq_desc[vector].param);
    }
}

/* Disable interrupt */
void SysInterruptMask(int vector)
{
    
}

void SysInterruptUmask(int vector)
{
    
}

/* TYPE
 *  #define LOW_LEVEL_SENSITIVE        0x00
 *  #define HIGH_LEVEL_SENSITIVE       0x40
 *  #define NEGATIVE_EDGE_TRIGGER      0x80
 *  #define POSITIVE_EDGE_TRIGGER      0xC0
 */
void SysInterruptSetType(int vector, int type)
{
    
}

#ifdef COM_USE_CONSOLE 
enConsoleResult list_interrupt(int argc, char **argv)
{
    int i;

    for (i = SYS_MIN_INT_SOURCE; i <= SYS_MAX_INT_SOURCE; i++)
    {
        if (_irq_desc[i].handler != interrupt_dummy_handler)
        {
#ifdef COM_USING_INTERRUPT_INFO            
            KPrintf("[%d] %s: %d\n", i, _irq_desc[i].name, _irq_desc[i].counter);
#endif            
        }
    }

    return CE_OK;
}
#endif

BGEIN_DEF_CMD(_commCommands)
    CMD_DEF_ALISA(interrupt, list_interrupt, "list registered interrupts")
END_DEF_CMD()

void SysInterruptInit(void)
{
    int i;

    for (i = SYS_MIN_INT_SOURCE; i <= SYS_MAX_INT_SOURCE; i++)
    {
        SysInterruptIntall(i, interrupt_dummy_handler, NULL, (char *)"dummy");
        SysInterruptMask(i);
    }

    CONSOLE_REG_CMD(_commCommands);
}

